package com.ctshk.rpc.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.system.dto.SysSupplierOrderMsgPageDTO;
import com.ctshk.rpc.system.entity.SysSupplierOrderMsg;
import com.ctshk.rpc.system.entity.SysSupplierOrderMsgSend;
import com.ctshk.rpc.system.entity.SysSupplierOrderMsgUser;
import com.ctshk.rpc.system.mapper.SysAssignmentMgtMapper;
import com.ctshk.rpc.system.mapper.SysAssignmentMgtSendMapper;
import com.ctshk.rpc.system.mapper.SysAssignmentMgtUserMapper;
import com.ctshk.rpc.system.mapper.SysSupplierOrderMsgSendMapper;
import com.ctshk.rpc.system.req.*;
import com.ctshk.rpc.system.service.ISysAssignmentMgtService;
import com.ctshk.rpc.system.service.ISystemMessageService;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 分配管理服务实现类
 * </p>
 *
 * @author 姜斌文
 * @since 2021-03-30
 */
@DubboService
public class SysAssignmentMgtServiceImpl extends ServiceImpl<SysAssignmentMgtMapper, SysSupplierOrderMsg> implements ISysAssignmentMgtService {

    @Autowired
    private SysAssignmentMgtMapper  sysAssignmentMgtMapper;
    @Autowired
    private SysAssignmentMgtUserMapper sysAssignmentMgtUserMapper;
    @Autowired
    private SysAssignmentMgtSendMapper sysAssignmentMgtSendMapper;
    @Autowired
    private SysSupplierOrderMsgSendMapper sysSupplierOrderMsgSendMapper;
    @Autowired
    private SysAssignmentMgtUserServiceImpl sysAssignmentMgtUserServiceImpl;
    @Autowired
    private ISystemMessageService messageService;
    
    @Override
    public void add(SysSupplierOrderMsgAddReq addObj, Long userId)
    {
        SysSupplierOrderMsg obj = new SysSupplierOrderMsg();
        LocalDateTime now=LocalDateTime.now();
        BeanUtils.copyProperties(addObj,obj);
        obj.setCreateId(userId);
        obj.setModifiedId(userId);
        obj.setGmtCreate(now);
        obj.setGmtModified(now);
        obj.setIsDeleted(IsDeletedCode.NO.getCode());
        if (null != addObj.getMessageType() && addObj.getMessageType().size() >0) {
        	String messageType = StringUtils.join(addObj.getMessageType().toArray(),",");
        	obj.setMessageType(messageType);
		}
        sysAssignmentMgtMapper.insert(obj);

        List<SysSupplierOrderMsgUser> somObjs = new ArrayList<>();
        List<String>  groupPersonIds = addObj.getGroupPersonIds();
        if (null != groupPersonIds && groupPersonIds.size() > 0) {
            for (int i = 0; i < groupPersonIds.size(); i++) {
                String groupUserId = groupPersonIds.get(i);
                String groupUserName = addObj.getGroupPersonNames().get(i);
                SysSupplierOrderMsgUser somuObj = new SysSupplierOrderMsgUser();
                somuObj.setUserId(Long.valueOf(groupUserId));
                somuObj.setUserName(groupUserName);
                somuObj.setRuleId(obj.getId());
                somuObj.setCreateId(obj.getCreateId());
                somuObj.setModifiedId(obj.getModifiedId());
                somuObj.setGmtCreate(obj.getGmtCreate());
                somuObj.setGmtModified(obj.getGmtModified());
                somuObj.setIsDeleted(IsDeletedCode.NO.getCode());
                somObjs.add(somuObj);
            }
        }
        if (null != somObjs && somObjs.size() > 0) {
            sysAssignmentMgtUserMapper.insertBatchSomeColumn(somObjs);
        }
    }

    @Override
    public void delete(SysSupplierOrderMsgDelReq delObj, Long userId) {
        LocalDateTime now=LocalDateTime.now();
        UpdateWrapper<SysSupplierOrderMsg> updateWrapper=new UpdateWrapper<>();
        updateWrapper.set("modified_id",userId);//修改人
        updateWrapper.set("is_deleted", IsDeletedCode.YES.getCode());//删除
        updateWrapper.set("gmt_modified",now);//修改时间
        updateWrapper.eq("id",delObj.getId());

        Long ruleId = delObj.getId();
        List<SysSupplierOrderMsgUser> dbSomuList = sysAssignmentMgtUserMapper.selectChildren(ruleId);
        if (null != dbSomuList && dbSomuList.size() > 0) {
            List<Long> ids = dbSomuList.stream().map(pp -> pp.getId()).collect(Collectors.toList());
            sysAssignmentMgtUserServiceImpl.removeByIds(ids);
        }
        sysAssignmentMgtMapper.update(null,updateWrapper);
    }

    @Override
    public void update(SysSupplierOrderMsgAddReq upObj, Long userId) {
        SysSupplierOrderMsg obj = new SysSupplierOrderMsg();
        BeanUtils.copyProperties(upObj,obj);
        LocalDateTime now=LocalDateTime.now();
        obj.setModifiedId(userId);
        obj.setGmtModified(now);
        if (null != upObj.getMessageType() && upObj.getMessageType().size() >0) {
        	String messageType = StringUtils.join(upObj.getMessageType().toArray(),",");
        	obj.setMessageType(messageType);
		}
        sysAssignmentMgtMapper.updateById(obj);

        //删除历史户组人员信息
        Long ruleId = upObj.getId();
        List<SysSupplierOrderMsgUser> dbSomuList = sysAssignmentMgtUserMapper.selectChildren(ruleId);
        if (null != dbSomuList && dbSomuList.size() > 0) {
            List<Long> ids = dbSomuList.stream().map(pp -> pp.getId()).collect(Collectors.toList());
            sysAssignmentMgtUserServiceImpl.removeByIds(ids);
        }

        //更新最新的用户组人员信息到DB
        List<SysSupplierOrderMsgUser> somObjs = new ArrayList<>();
        List<String>  groupPersonIds = upObj.getGroupPersonIds();
        if (null != groupPersonIds && groupPersonIds.size() > 0) {
            for (int i = 0; i < groupPersonIds.size(); i++) {
                String groupUserId = groupPersonIds.get(i);
                String groupUserName = upObj.getGroupPersonNames().get(i);
                SysSupplierOrderMsgUser somuObj = new SysSupplierOrderMsgUser();
                somuObj.setUserId(Long.valueOf(groupUserId));
                somuObj.setUserName(groupUserName);
                somuObj.setRuleId(obj.getId());
                somuObj.setCreateId(obj.getModifiedId());
                somuObj.setModifiedId(obj.getModifiedId());
                somuObj.setGmtCreate(obj.getGmtModified());
                somuObj.setGmtModified(obj.getGmtModified());
                somuObj.setIsDeleted(IsDeletedCode.NO.getCode());
                somObjs.add(somuObj);
            }
        }
        if (null != somObjs && somObjs.size() > 0) {
            sysAssignmentMgtUserMapper.insertBatchSomeColumn(somObjs);
        }
    }

    @Override
    public PageResponse<SysSupplierOrderMsgPageDTO> assignmentMgtList(SysSupplierOrderMsgPageReq supplierOrderMsgPageReq, TokenUser tokenUser) {
            IPage<SysSupplierOrderMsg> page = new Page<SysSupplierOrderMsg>(supplierOrderMsgPageReq.getPageNo(), supplierOrderMsgPageReq.getPageSize());
            	IPage<SysSupplierOrderMsg> iPage = sysAssignmentMgtMapper.assignmentMgtList(page, supplierOrderMsgPageReq);
                List<SysSupplierOrderMsg> supplierOrderMsgList = iPage.getRecords();
                List<SysSupplierOrderMsgPageDTO> pageDTOList = EntityUtil.copyList(supplierOrderMsgList,
                        SysSupplierOrderMsgPageDTO.class);
                return new PageResponse<>(pageDTOList, iPage.getCurrent() == 1,
                        iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()),
                        iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

	@Override
	public void sendStationInfo(SysSendStationInfoMsgReq obj, Long operationUserId) {
		List<SysSupplierOrderMsg> supplierOrderMsgList= sysAssignmentMgtMapper.selectValidDataByType(obj.getBookingType());
		if (null != supplierOrderMsgList && supplierOrderMsgList.size() >0) {
			SysSupplierOrderMsg supplierOrderMsg = supplierOrderMsgList.get(0);
			Long keyId = supplierOrderMsg.getId();
			SysMessageReq messageReq = new SysMessageReq();
	        BeanUtils.copyProperties(obj, messageReq);
	        String[] groupUserIds = supplierOrderMsg.getGroupPersonIds().split(",");
			String[] groupUserNames = supplierOrderMsg.getGroupPersonNames().split(",");
			String[] keyRuleUserIds = supplierOrderMsg.getGroupRuleUserIds().split(",");
			List<String> sendType = Arrays.asList(supplierOrderMsg.getMessageType().split(",")); // 发送类型1：短信;2：邮件;3：站内消息
			sendMessage(sendType,keyId, keyRuleUserIds, messageReq, supplierOrderMsg.getChargePersonId(), supplierOrderMsg.getChargePersonName(),
					groupUserIds, new String[]{supplierOrderMsg.getChargePersonName()}, "single-notSave", operationUserId);
			if (supplierOrderMsg.getRuleType() == 1) { // 方式1：轮询发送
				List<SysSupplierOrderMsgSend> sendList= sysAssignmentMgtSendMapper.selectSupplierOrderMsgSendByRuleId(
						supplierOrderMsg.getGroupRuleUserIds(), keyId);
				Map<String, String> userRuleIdMap = new HashMap<String, String>();
				Map<String, Integer> userSendCount = getUserSendCount(groupUserIds, groupUserNames, sendList, keyRuleUserIds, userRuleIdMap);
				Long sendUserId = 0L;
				String sendUserName = "";
				if(null != userSendCount){ // 获取发送次数最小的
					sendUserId = getMinValue(userSendCount); // 获取轮询本次要发送信息的用户ID
					String [] tempName = userRuleIdMap.get(String.valueOf(sendUserId)).split(",");
					sendUserName = tempName[1];
					keyRuleUserIds = new String[]{userRuleIdMap.get(String.valueOf(sendUserId)).split(",")[0]};
				} else { // 随机取一个发送
					sendUserId = Long.valueOf(groupUserIds[0]);
					sendUserName = groupUserNames[0];
				}
				sendMessage(sendType,keyId, keyRuleUserIds, messageReq, sendUserId, sendUserName, groupUserIds,groupUserNames,"single", operationUserId);
			} else { // 方式2：全部发送
				sendMessage(sendType,keyId, keyRuleUserIds, messageReq, null, null, groupUserIds, groupUserNames, "all", operationUserId);
			}
		}
	}

	@Override
	public Long getPollingUserId(Long type) {
		List<SysSupplierOrderMsg> supplierOrderMsgList= sysAssignmentMgtMapper.selectValidDataByType(type);
		Long userId = null;
		if (null != supplierOrderMsgList && supplierOrderMsgList.size() >0) {
			SysSupplierOrderMsg supplierOrderMsg = supplierOrderMsgList.get(0);
			if (supplierOrderMsg.getRuleType() == 1) {
				Long keyId = supplierOrderMsg.getId();
				String[] groupUserIds = supplierOrderMsg.getGroupPersonIds().split(",");
				String[] groupUserNames = supplierOrderMsg.getGroupPersonNames().split(",");
				String[] keyRuleUserIds = supplierOrderMsg.getGroupRuleUserIds().split(",");
				List<SysSupplierOrderMsgSend> sendList= sysAssignmentMgtSendMapper.selectSupplierOrderMsgSendByRuleId(
						supplierOrderMsg.getGroupRuleUserIds(), keyId);
				Map<String, String> userRuleIdMap = new HashMap<String, String>();
				Map<String, Integer> userSendCount = getUserSendCount(groupUserIds, groupUserNames, sendList, keyRuleUserIds, userRuleIdMap);
				Long sendUserId = 0L;
				String sendUserName = "";
				if(null != userSendCount){ // 获取发送次数最小的
					userId = getMinValue(userSendCount); // 获取轮询本次要发送信息的用户ID
				} else { // 随机取一个发送
					userId = Long.valueOf(groupUserIds[0]);
				}
			} else {
				return userId;
			}
		}
		return userId;
	}

	/**
	 * 发送消息
	 * @param sendType 发送类型1：短信;2：邮件;3：站内消息
	 * @param keyId 用于入库发送记录表的分配管理表主键ID
	 * @param keyRuleUserIds 用于入库发送记录表的分配管理用户表主键ID
	 * @param messageReq 站内消息发送对象
	 * @param sendUserId 站内消息-单个用户ID
	 * @param sendUserName 站内消息-单个用户名称
	 * @param groupUserIds 站内消息-全部用户ID
	 * @param groupUserIds 站内消息-全部用户Name
	 * @param type 类型-单个发送 or 全部发送
	 * @param operationUserId 当前操作人用户ID
	 */
	private void sendMessage(List<String> sendType, Long keyId, String[] keyRuleUserIds, SysMessageReq messageReq,
			Long sendUserId, String sendUserName, String[] groupUserIds, String[] groupUserNames, String type, Long operationUserId) {
		if (sendType.contains("1")) {
			
		}
		if (sendType.contains("2")) {
			
		}
		if (sendType.contains("3")) {
			sendStationMesage(messageReq, keyId, keyRuleUserIds, sendUserId, sendUserName, groupUserIds, groupUserNames, type, operationUserId);
		}
	}

	/**
	 * 发送站内消息
	 * @param messageReq 发送消息对象
	 * @param keyId 用于入库发送记录表的分配管理表主键ID
	 * @param keyRuleUserIds 用于入库发送记录表的分配管理用户表主键ID
	 * @param userId 单个发送时的用户ID
	 * @param groupUserIds 全部用户发送时的用户ID集合
	 * @param sendUserName 站内消息-单个用户名称
	 * @param groupUserIds 站内消息-全部用户Name
	 * @param type 类型-all全部发送，single-单个发送
	 * @param operationUserId 当前操作人用户ID
	 */
	private void sendStationMesage(SysMessageReq messageReq, Long keyId, String[] keyRuleUserIds,
			Long sendUserId, String sendUserName, String[] groupUserIds, String[] groupUserNames, String type, Long operationUserId) {
		LocalDateTime now = LocalDateTime.now();
		List<SysSupplierOrderMsgSend> supplierOrderMsgSends = new ArrayList<SysSupplierOrderMsgSend>();
		if ("single".equals(type) || "single-notSave".equals(type)) {
	        messageReq.setReceivingUserId(sendUserId);
	        messageReq.setSendingTime(now);
			messageService.add(messageReq, operationUserId);
			if ("single".equals(type)) {
				SysSupplierOrderMsgSend msgSendObj = new SysSupplierOrderMsgSend();
				msgSendObj.setRuleId(keyId);
				msgSendObj.setRuleUserId(Long.valueOf(keyRuleUserIds[0]));
				msgSendObj.setUserId(sendUserId);
				msgSendObj.setUserName(sendUserName);
				supplierOrderMsgSends.add(msgSendObj);
			}
		} else if("all".equals(type)){
			for (int i = 0; i < groupUserIds.length; i++) {
				String userIdstr = groupUserIds[i];
		        messageReq.setReceivingUserId(Long.valueOf(userIdstr));
		        messageReq.setSendingTime(now);
				messageService.add(messageReq, operationUserId);
				SysSupplierOrderMsgSend msgSendObj = new SysSupplierOrderMsgSend();
				msgSendObj.setRuleId(keyId);
				msgSendObj.setRuleUserId(Long.valueOf(keyRuleUserIds[i]));
				msgSendObj.setUserId(Long.valueOf(userIdstr));
				msgSendObj.setUserName(groupUserNames[i]);
				supplierOrderMsgSends.add(msgSendObj);
			}
		}
		if(!"single-notSave".equals(type)){
			sysSupplierOrderMsgSendMapper.insertBatchSomeColumn(supplierOrderMsgSends);
		}
	}

	/**
	 * 组装MAP，用于后续的比对发送次数取值
	 * @param groupUserIds 分组用户ID集合
	 * @param groupUserNames 分组用户Name集合
	 * @param sendList DB查询的已经发送过的人员集合
	 * @param userRuleIdMap 分配管理用户主键ID集合
	 * @param keyRuleUserIds 用户存放userId对应的主键ID
	 * @return Map
	 */
	private Map<String, Integer> getUserSendCount(String[] groupUserIds, String [] groupUserNames,
			List<SysSupplierOrderMsgSend> sendList, String[] keyRuleUserIds, Map<String, String> userRuleIdMap) {
		Map<String, Integer> userSendCount = new HashMap<String, Integer>();
		if (null == sendList || sendList.size() == 0) {
			return null;
		}
		for (int i = 0; i < groupUserIds.length; i++) {
			String userId=  groupUserIds[i];
			userSendCount.put(userId, 0);
			userRuleIdMap.put(userId, keyRuleUserIds[i]+","+groupUserNames[i]);
		}
		for (SysSupplierOrderMsgSend send : sendList) {
			String sendUserId = String.valueOf(send.getUserId());
			if (userSendCount.containsKey(sendUserId)) {
				Integer count = userSendCount.get(sendUserId);
				userSendCount.put(sendUserId, ++count);
			}
			if (!userRuleIdMap.containsKey(sendUserId)) {
				userRuleIdMap.put(sendUserId, String.valueOf(send.getRuleUserId()) +","+send.getUserName());
			}
		}
		return userSendCount;
	}

	 /**
     * 求Map<K,V>中Value(值)的最小值并返回Key
     * @param map 用户发送站内信息次数集合
     * @return Long 用户ID
     */
    public Long getMinValue(Map<String, Integer> map) {
        if  (map == null )  return  null ;
        Integer value= map.values().stream().sorted().findFirst().get();

        List<String> collect = map.entrySet()
                .stream()
                .filter(kvEntry -> Objects.equals(kvEntry.getValue(), value))
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
        //若值有重复的，则collect集合中有多个key，按照业务需求自行取值
        return Long.valueOf(collect.get(0));
    }
}